package com.cloud.pole.weixin.service.impl;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.druid.support.json.JSONUtils;
import com.cloud.pole.common.constant.CommonConstants;
import com.cloud.pole.common.exception.BaseException;
import com.cloud.pole.common.util.security.MD5Utils;
import com.cloud.pole.weixin.biz.WxAppBiz;
import com.cloud.pole.weixin.biz.WxPayJoinBiz;
import com.cloud.pole.weixin.model.entity.WxApp;
import com.cloud.pole.weixin.model.entity.WxPayJoin;
import com.cloud.pole.weixin.service.WxPayService;
import com.cloud.pole.weixin.util.wechat.Sha1Util;
import com.cloud.pole.weixin.util.wxpay.TenpayUtil;
import com.cloud.pole.weixin.util.wxpay.WXPay;
import com.cloud.pole.weixin.util.wxpay.WXPayUtil;
import com.cloud.pole.weixin.util.wxpay.WxConfig;

import lombok.extern.slf4j.Slf4j;

/*
*2019年4月30日
*cloud-weixin
*author:frank-chen
*/
@Slf4j
@Service
public class WxPayServiceImpl implements WxPayService {
	@Autowired
	private WxAppBiz wxAppBiz;
	@Autowired
	private WxPayJoinBiz wxPayJoinBiz;
	
	@Override
	public String unifiedOrderJsApi(Integer payJoinId, String outTradeNo, Long totalFee, String openid, String redirectUri) throws Exception {
		WxPayJoin wxPayJoin = wxPayJoinBiz.selectByPrimaryKey(payJoinId);
		if(wxPayJoin == null || wxPayJoin.getJoinStatus().intValue() !=  WxPayJoin.JOIN_STATUS_OK) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "payJoinId错误");
		}
		WxApp wxApp = wxAppBiz.selectByPrimaryKey(wxPayJoin.getWxAppId());
		if(wxApp == null || wxApp.getAppStatus().intValue() !=  WxApp.APP_STATUS_OK) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "wxAppId错误");
		}
		String strResponse = "";
		String currTime = TenpayUtil.getCurrTime();
		// 8位日期
		String strTime = currTime.substring(8, currTime.length());
		// 四位随机数
		String strRandom = TenpayUtil.buildRandom(4) + "";
		// 10位序列号,可以自行调整。
		String nonce_str = strTime + strRandom;
		nonce_str = MD5Utils.md5Hex(nonce_str);
		
		WxConfig config = new WxConfig(wxApp.getAppId(), wxApp.getMchid(), wxApp.getPayKey());
		WXPay wxPay = new WXPay(config, null, true, true);
        Map<String, String> data = new HashMap<String, String>();
        data.put("body", wxPayJoin.getJoinName());
        data.put("out_trade_no", outTradeNo);
        data.put("fee_type", "CNY");
//      data.put("total_fee", Long.toString(totalFee));
        data.put("total_fee", "1");
        data.put("spbill_create_ip", wxPayJoin.getSpbillCreateIp());
        data.put("notify_url", wxPayJoin.getNotifyUrl());
        data.put("trade_type", "JSAPI");  //H5支付
        data.put("openid", openid);
        data.put("nonce_str", nonce_str);   // 随机字符串小于32位

        /**
            * 附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。
            * 用在更新业务系统状态
         */
        data.put("attach", redirectUri);   
        try {
            Map<String, String> resp = wxPay.unifiedOrder(data);
            if(resp == null) {
    			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "调用支付失败");
            }
            String returnCode = resp.get("return_code");
            String resultCode = resp.get("result_code");
            if(returnCode == null || !StringUtils.equals(returnCode, "SUCCESS")) {
            	log.error(resp.toString());
    			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "调用支付失败");
            }
            if(resultCode == null || !StringUtils.equals(resultCode, "SUCCESS")) {
            	log.error(resp.toString());
    			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "调用支付失败");
            }
			String prepay_id = resp.get("prepay_id");

    		//生成签名
			Map<String, String> finalpackage = new HashMap<String, String>();
			String timestamp = Sha1Util.getTimeStamp();
			String packages = "prepay_id=" + prepay_id;
			finalpackage.put("appId", wxApp.getAppId());
			finalpackage.put("nonceStr", nonce_str);
			finalpackage.put("package", packages);
			finalpackage.put("signType", "MD5");
			finalpackage.put("timeStamp", timestamp);
							
			// 签名
			String paySign = WXPayUtil.generateSignature(finalpackage, wxApp.getPayKey());
			//System.out.println(finalpackage.toString());
			Map<String, String> resultMap = new HashMap<String, String>();
			resultMap.put("appId", wxApp.getAppId());
			resultMap.put("timeStamp", timestamp);
			resultMap.put("nonceStr", nonce_str);
			resultMap.put("package", packages);
			resultMap.put("signType",  "MD5");
			resultMap.put("paySign", paySign);
			//可以不传
			resultMap.put("openid", openid);
			//可以不传
			resultMap.put("money", Long.toString(totalFee));
			strResponse = JSONUtils.toJSONString(resultMap);

        } catch (Exception e) {
            e.printStackTrace();
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "调用支付失败");
        }
        return strResponse;
	}
}
